/*
  ^ 索引访问类型
  ^ 我们可以使用索引访问类型来查找另一种类型的特定属性：
 */

type Person1 = {
    name: string;
    age: number;
    ses: string;
};

type Person1Name1 = Person1[keyof Person1];
type Person1Name2 = Person1["age"];
// let dxd:Person1Name=5
let dxd: Person1Name1 = "sad";


/**
 * ^ 使用任意类型进行索引的另一个示例是使用 number
 * ^ 来获取数组元素的类型。我们可以将它与 typeof 结合起来，以方便地捕获数组字面量的元素类型：
 */
    //! 注意当使用const 定义变量时返回的值
const keys = "age";

// ! type KK = Person1[keys]; //会报错  keys”表示值，但在此处用作类型。是否指“类型 keys”?
// 解决
// * type KK = Person1[typeof keys];
type keys = "age";

type KK = Person1[keys];


const myarr = [
    {name: "Alice", age: 15},
    {address: "北京大学", age: 20},
];

type Person11 = { name: string, age: number } | { address: string, age: number }; //返回数组对象 number相当于[] 遍历数组返回类型
type Person12 = typeof myarr[number]

// 为啥sseas2会报错
// | 类型来源   | 行为     | 赋值混合字段是否报错 |
// | ------ | ------ | ---------- |
// | 显式联合类型 | 宽松，允许  | ❌ 不报错（宽容）  |
// | 推导联合类型 | 更精确，严格 | ✅ 报错       |
// | 使用变量赋值 | 严格校验   | ✅ 报错       |


// ✅ 真相：这是 TypeScript 中 "对象字面量直接赋值" 与 "变量赋值" 类型检查行为不同 导致的
// 解释一：字面量直接赋值时 TS 会“宽容合并字段”
let sseas: Person11 = {name: "Alice", age: 15, address: ""};

// 😨 解释二：Person12 是通过 typeof myarr[number] 得到的类型，这个类型更“精确”，检查也更严格
let sseas2: Person12 = {name: "Alice", age: 15, address: ""}

type Age = (typeof myarr)[number]["age"];
type address = (typeof myarr)[number]["address"];
let dse: address = ""

